package action;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpSession;

import model.User;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.struts2.ServletActionContext;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import util.ResponseUtil;
import util.StringUtil;

import common.Constants;

import dao.UserDao;
import exception.SystemException;

public class LoginAction extends BaseAction {

	private static final long serialVersionUID = 1L;
	private User user;
	private String delId;
	private String id;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getDelId() {
		return delId;
	}

	public void setDelId(String delId) {
		this.delId = delId;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	UserDao userDao = new UserDao();

	@Override
	public String execute() throws Exception {

		HttpSession session = request.getSession();
		JSONObject result = new JSONObject();
		try {
			if (StringUtil.isEmpty(user.getUserName())
					|| StringUtil.isEmpty(user.getPassword())) {
				result.put("errorMsg", "模式名或密码不能为空!");
			} else {
				User currentUser = userDao.login(user);
				if (currentUser != null) {
					result.put("success", "true");
					session.setAttribute(Constants.KEY_CURRENT_USER, currentUser);
					result.put("initialized", isInitialized());
					userDao.saveUser(currentUser);
				} else {
					request.setAttribute("error", "模式名和密码无法识别！");
					result.put("errorMsg", "模式名和密码无法识别！");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("errorMsg", e.getMessage());
		}
		ResponseUtil.write(ServletActionContext.getResponse(), result);
		return null;
	}

	public String logout() throws Exception {
		HttpSession session = request.getSession();
		session.removeAttribute(Constants.KEY_CURRENT_USER);
		JSONObject result = new JSONObject();
		result.put("success", "true");
		ResponseUtil.write(ServletActionContext.getResponse(), result);
		return super.execute();
	}

	public String getHistoryUsers() throws Exception {
		JSONObject result = new JSONObject();
		try {
			JSONArray jsonArray = userDao.findAllUser();
			result.put("rows", jsonArray);
			result.put("total", jsonArray.size());
			result.put("success", "true");
		} catch (Exception e) {
			e.printStackTrace();
			result.put("errorMsg", e.getMessage());
		}
		ResponseUtil.write(ServletActionContext.getResponse(), result);
		return null;
	}

	public String saveUser() throws Exception {
		JSONObject result = new JSONObject();
		try {
			int saveNums = userDao.saveUser(user);
			if (saveNums > 0) {
				result.put("success", "true");
			} else {
				result.put("success", "false");
				result.put("errorMsg", "保存失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("errorMsg", e.getMessage());
		}
		ResponseUtil.write(ServletActionContext.getResponse(), result);
		return null;
	}

	public String deleteUser() throws Exception {
		JSONObject result = new JSONObject();
		try {
			int delNums = userDao.deleteUser(user);
			if (delNums > 0) {
				result.put("success", "true");
				result.put("delNums", delNums);
			} else {
				result.put("errorMsg", "删除失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("errorMsg", e.getMessage());
		}
		ResponseUtil.write(ServletActionContext.getResponse(), result);
		return null;
	}

	public void loadJava() throws Exception {
		List<String> messages = new ArrayList<String>();
		String javaClass = this.getClass().getClassLoader().getResource("")
				.getPath()
				+ "dataPrivacy15.class";
		Runtime run = Runtime.getRuntime();// 返回与当前 Java 应用程序相关的运行时对象
		JSONObject result = new JSONObject();
		
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute(Constants.KEY_CURRENT_USER);
		String url = user.getUrl();
		String server = url.split("@")[1];
		try {
			String cmd = getOracleHomePath() + "/bin/"
					+ getConfigCommand("loadjava") + " -verbose -schema "
					+ Constants.ADMIN_USER_NAME + " -thin -user "
					+ Constants.ADMIN_USER_NAME + "/"
					+ Constants.ADMIN_USER_PASSWORD + "@" + server
					+ " " + javaClass;
			System.out.println("loadjava:" + cmd);
//			messages.add("开始向数据库中加载java类...");
			Process p = run.exec(cmd);// 启动另一个进程来执行命令
			BufferedInputStream in = new BufferedInputStream(p.getInputStream());
			BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
			String lineStr;
			while ((lineStr = inBr.readLine()) != null) {
				// 获得命令执行后在控制台的输出信息
//				messages.add(lineStr);
			}
			// 检查命令是否执行失败。
			if (p.waitFor() != 0) {
				if (p.exitValue() == 1) {// p.exitValue()==0表示正常结束，1：非正常结束
					System.err.println("命令执行失败!");
//					messages.add("命令执行失败!");
				} else {
//					messages.add("命令执行完毕!");
				}
			}
			inBr.close();
			in.close();
			result.put("initialized", true);
		} catch (Exception e) {
			e.printStackTrace();
			messages.add(e.getMessage());
			result.put("initialized", false);
		}
		JSONArray jsonArray = JSONArray.fromObject(messages);
		result.put("rows", jsonArray);
		result.put("total", jsonArray.size());
		result.put("success", "true");
		ResponseUtil.write(ServletActionContext.getResponse(), result);
	}
	
	public void initializeFunctions() throws Exception {
		JSONObject result = new JSONObject();
		List<String> messages = new ArrayList<String>();
		messages.add("开始创建函数...");
		try {
			HttpSession session = request.getSession();
			List<String> sqls = getConfigFunctionsSql();
			userDao.initializeFunctions(session, sqls);
			userDao.initializeFunctionsPrivilege(session, getConfigFunctions());
			messages.add("函数初始化完毕！共添加" + sqls.size() + "个！");
			result.put("initialized", true);
		} catch (Exception e) {
			e.printStackTrace();
			messages.add(e.getMessage());
			result.put("initialized", false);
		}
		JSONArray jsonArray = JSONArray.fromObject(messages);
		result.put("rows", jsonArray);
		result.put("total", jsonArray.size());
		result.put("success", "true");
		ResponseUtil.write(ServletActionContext.getResponse(), result);
	}

	private String getOracleHomePath() throws SystemException {
		String oracleHome = System.getenv("ORACLE_HOME");
		if (oracleHome != null) {
			return oracleHome;
		} else {
			throw new SystemException("无法获取ORACLE_HOME路径");
		}
	}

	private boolean isInitialized() {
		try {
			JSONArray jsonArray = userDao.getConfigFunctions(request.getSession());
			List<String> configFunctions = getConfigFunctions();
			for (int i = 0; i < configFunctions.size(); i++) {
				if (!hasFunction(jsonArray, configFunctions.get(i))) {
					return false;
				}
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	private boolean hasFunction(JSONArray jsonArray, String functionName) {
		for (int i = 0; i < jsonArray.size(); i++) {
			JSONObject jo = jsonArray.getJSONObject(i);
			if (jo.containsKey("NAME") && jo.get("NAME").equals(functionName.toUpperCase())) {
				return true;
			}
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	private List<String> getConfigFunctions() throws Exception {
		String path = this.getClass().getClassLoader().getResource("")
				.getPath();
		File f = new File(path + "/config.xml");
		SAXReader reader = new SAXReader();
		Document doc = reader.read(f);
		Element root = doc.getRootElement();
		Element functions = root.element("functions");
		Element foo;
		List<String> functionNames = new ArrayList<String>();
		for (Iterator<Element> i = functions.elementIterator("function"); i
				.hasNext();) {
			foo = i.next();
			functionNames.add(foo.attributeValue("name"));
		}
		return functionNames;
	}
	
	@SuppressWarnings("unchecked")
	private List<String> getConfigFunctionsSql() throws Exception {
		String path = this.getClass().getClassLoader().getResource("")
				.getPath();
		File f = new File(path + "/config.xml");
		SAXReader reader = new SAXReader();
		Document doc = reader.read(f);
		Element root = doc.getRootElement();
		Element functions = root.element("functions");
		Element foo;
		List<String> sqls = new ArrayList<String>();
		for (Iterator<Element> i = functions.elementIterator("function"); i
				.hasNext();) {
			foo = i.next();
			sqls.add(foo.getText());
		}
		return sqls;
	}

	@SuppressWarnings("unchecked")
	private String getConfigCommand(String command) throws Exception {
		String path = this.getClass().getClassLoader().getResource("")
				.getPath();
		File f = new File(path + "/config.xml");
		SAXReader reader = new SAXReader();
		Document doc = reader.read(f);
		Element root = doc.getRootElement();
		Element functions = root.element("commands");
		String cmd = null;
		for (Iterator<Element> i = functions.elementIterator("command"); i
				.hasNext();) {
			Element foo = i.next();
			if (foo.attributeValue("name").equals(command)) {
				cmd = foo.attributeValue("value");
				break;
			}
		}
		return cmd;
	}

	public static void main(String[] args) {
		try {
			new LoginAction().loadJava();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
